#include "stdint.h"
#include "stdio.h"
#include "f16.h"

f16Type __float2half(float fValue)
{
    f32Type *pf32Value = (f32Type *)&fValue;
    uint32_t sign = pf32Value->sign, fraction = pf32Value->fraction >> 13, value;
    int32_t exponent = pf32Value->exponent;

    exponent -= 127;
    exponent = (exponent > 16) ? 16 : ((exponent < -16) ? -16 : exponent);
    exponent += 15;

    if((exponent == 0x1F) && (pf32Value->exponent >= (127 + 15)) && (pf32Value->exponent != 0xFF))
    {
        fraction = 0;
    }

    value = (sign << 15) | (exponent << 10) | fraction;

    return *(f16Type *)&value;
}

float __half2float(f16Type f16Value)
{
    uint32_t sign = f16Value.sign, fraction = (uint32_t)f16Value.fraction << 13, value;
    int32_t exponent = f16Value.exponent;

    exponent = (exponent == 0x1F) ? 0xFF : ((exponent == 0) ? 0 : exponent + (127 - 15));

    value = (sign << 31) | (exponent << 23) | fraction;

    return *(float *)&value;
}

